package com.doria.consumer.controller;

import cn.hutool.core.collection.CollUtil;
import com.doria.consumer.controller.feign.FeignProviderUserController;
import com.doria.common.exception.ServerMissException;
import com.doria.common.pojo.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Objects;
import java.util.Random;

import static org.springframework.http.ResponseEntity.ok;

@RestController
@RequestMapping("/consumer")
@Slf4j
public class ConsumerUserController {

    private final RestTemplate restTemplate;
    private final DiscoveryClient discoveryClient;
    private final FeignProviderUserController feignConsumerUserClient;

    public ConsumerUserController(DiscoveryClient discoveryClient, RestTemplate restTemplate, FeignProviderUserController feignConsumerUserClient) {
        this.discoveryClient = discoveryClient;
        this.restTemplate = restTemplate;
        this.feignConsumerUserClient = feignConsumerUserClient;
    }

    @GetMapping("/restTemplateGetUser/{id}")
    public ResponseEntity<User> restTemplateGetUser(@PathVariable("id") String id) {
        log.info("消费者收到请求,data内容:[" + id + "],开始消费服务....");
       /*远程调用Provide服务中的getUser接口，原始方法，不推荐用
            使用RestTemplate
            1. 定义Bean  restTemplate
            2. 注入Bean
            3. 调用方法
         */
        //配置请求Url
        String url = "http://127.0.0.1:8088/provider/getUser/" + id;
        //调用
        User user = restTemplate.getForObject(url, User.class);
        return ok(user != null ? user : new User());
    }


    @GetMapping("/ribbonRestTemplateGetUser/{id}")
    public ResponseEntity<User> ribbonRestTemplateGetUser(@PathVariable("id") String id) {
        log.info("消费者收到请求,data内容:[" + id + "],开始消费服务....");
       /*远程调用Provide服务中的getUser接口，原始方法，不推荐用
            使用RestTemplate
            1. 定义Bean  restTemplate
            2. 注入Bean
            3. 调用方法
         */
        //配置请求Url
        String url = "http://eureka-provider:8088/provider/getUser/" + id;
        //调用
        User user = restTemplate.getForObject(url, User.class);
        return ok(user != null ? user : new User());
    }

    // Discover获取url集合的方式进行调用
    @GetMapping("/DiscoverClientGetUser/{id}")
    public ResponseEntity<User> DiscoverClientGetUser(@PathVariable("id") String id) {
        log.info("请求参数：" + "[" + id + "]");
        List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");//这里输入我们服务提供者注册往Eureka时配置的服务名称，通过这个获取他的rul进行调用
        //获取到的就是该服务的所有url路由，为什么是集合呢。因为集群啊，没有集群用个吉尔的cloud;如果只有一个就是一个调用咯。看你怎么操作这个集合就怎么进行负载均衡了
        if (CollUtil.isEmpty(instances)) {
            // 集合没有数据，抛出服务异常
            throw new ServerMissException(4041, "没有服务被发现");
        }
        //根据集合长度随机获取一个服务提供者
        ServiceInstance instance = instances.get(new Random().nextInt(instances.size()));
        int port = instance.getPort();
        String host = instance.getHost();
        String uri = "/provider/getUser/"+id;
        //获取host和port组成url发起请求
        String url="http://"+host+":"+port+uri;
        User user = restTemplate.getForObject(url, User.class);
        return ok(Objects.requireNonNull(user));
    }

    /**
     * Feign形式的服务调用
     * @param id
     * @return
     */
    @GetMapping("/FeignClientGetUser/{id}")
    public ResponseEntity<User> FeignClientGetUser(@PathVariable("id") String id){
        ResponseEntity<User> user = feignConsumerUserClient.getUser(id);
        return user;
    }
}
